home *** CD-ROM | disk | FTP | other *** search
/ Die Ultimative Software-P…i Collection 1996 & 1997 / Die Ultimative Software-Pakete CD-ROM fur Atari Collection 1996 & 1997.iso / i / internet / software / lprsr / spd.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-08-05  |  24.1 KB  |  976 lines

  1. /************************************************************************/
  2. /*                                                                      */
  3. /*    HPspd.c                                                           */
  4. /*                                                                      */
  5. /*    Durch bloßes Ändern der Extension im Dateinamen, läßt sich Pro-   */
  6. /*    gramm als normale GEM-Anwendung oder aber als Accessory betrei-   */
  7. /*    ben.                                                              */
  8. /*    Das Programm lenkt Druckerausgaben auf den Netzwerkdrucker um.    */
  9. /*                                                                      */
  10. /*    Copyright (c)  FORTEC/pm 1993                                     */
  11. /*                                                                      */
  12. /************************************************************************/
  13.  
  14. /* -------------------------------------------------------------------- */
  15. /*    Headerdateien einbinden.                                          */
  16. /* -------------------------------------------------------------------- */
  17.  
  18. #include <aes.h>
  19. #include <stdio.h>
  20. #include <tos.h>
  21. #include <vdi.h>
  22. #include <string.h>
  23. #include <stdlib.h>
  24. #include <ctype.h>
  25. #include <time.h>
  26. #include "tcpdef.h"
  27.  
  28. #define noDEBUG
  29.  
  30. #define LINESIZE 70L
  31. #define NUMLINES 8
  32.  
  33. #define WINW     500
  34. #define WINH     200
  35. #define ZH 6
  36.  
  37. #define TRUE 1
  38. #define FALSE 0
  39. #define mmin(a,b) (((a) < (b)) ? (a) : (b))
  40.  
  41. #define INBUFSIZE     1024
  42. #define FILE_BUF_SIZE 4096
  43. #define BUFS          4096L
  44.  
  45. #define SYSBASE ((SYSHDR*)0x4f2L)
  46.  
  47. static DESTI desti;
  48. static TCPSTAT tstat;
  49.  
  50. char *myid = "@(#)ANS-HPSPD 1.0ß pm93";
  51.  
  52. static BASPAG **oldpd;
  53.  
  54. static char *term;
  55. static int tcp_buff = 2048;
  56. static char data[INBUFSIZE];
  57.  
  58. static char file_buffer[FILE_BUF_SIZE];
  59. static char filename[50];
  60. static long number,timev;
  61. static int tcp_ok;
  62. static char *printer;
  63. static char *printhost;
  64. static char *hostname;
  65. static char *user;
  66. static long lendata;
  67. static long lensent;
  68. static int tcp;
  69. static char response;
  70. static long filelength;
  71. static char * file_to_print;
  72. static int fin;
  73. static int
  74.  ex, ey,
  75.  kstate,
  76.  key,
  77.  clicks,
  78.  event,
  79.  state;
  80. int pipe[8];
  81. static int quit;
  82.  
  83. static char log_text[NUMLINES][LINESIZE+1];
  84. char text[2*LINESIZE];
  85. static int  line_tab[NUMLINES];
  86. static int  actline = 0;
  87.  
  88. #define LPR_PORT    515
  89.  
  90. int flag = 0;
  91. static long ix = 0;
  92. static int fh = 0;
  93. static int closeflag = 0;
  94. static int escflag = 0;
  95. static int printflag = 0;
  96. static int or = 0;
  97. static long ox = 0;
  98. static char spfilename[] = "hpprnd00.pco";
  99. static char path[128];
  100. static char bf[BUFS];
  101.  
  102. /* -------------------------------------------------------------------- */
  103. /*    Extern definierte globale Variablen.                              */
  104. /* -------------------------------------------------------------------- */
  105. extern int _app;
  106. extern long oldgem;
  107. extern long oldbios;
  108. extern long grpgem;
  109. extern long grpbios;
  110.  
  111. /* -------------------------------------------------------------------- */
  112. /*    Globale Variablen.                                                */
  113. /* -------------------------------------------------------------------- */
  114. int get_response(void);
  115. long set_pd(void);
  116. long restore_pd(void);
  117. void output1(int o_len, char *o_str);
  118. void output(char *o_str);
  119. void printfile(int fin);
  120. void spoolfile(void);
  121. int connect(char * host, int port);
  122. void redraw_window( int all );
  123. int handle_message(int *pipe);
  124. void multi( void );
  125. void event_loop( void );
  126. void spool(void);
  127.  
  128. static int  whandle;          /* Handle für geöffnetes Fenster.   */
  129. static char title[] = "HP-Printer Dämon";  /* Titelzeile des Fensters.         */
  130. static int  gl_wchar;        /* Größe und Breite eines Buchsta-  */
  131. static int gl_hchar;        /* ben (wichtig falls mit unter-    */
  132. static int gl_wbox;        /* schiedlichen Bildschirmauflö-    */
  133. static int gl_hbox;          /* sungen gearbeitet wird) bzw.     */
  134.                     /* einer Box.                       */
  135. static int  phys_handle;    /* Handles für GEM und VDI.         */
  136. static int handle;
  137. static int  max_x;            /* Maximale Größe der Arbeitsfläche */
  138. static int max_y;
  139. int  appl_id;        /* Identifikationsnummer des Prog.  */
  140. int menu_id;              /* Id.-nummer im Menü 'Desk'.       */
  141.  
  142. static int line_height = 8;
  143. static int cell_width = 8;
  144.  
  145. static int dum;
  146. static int x,y,w,h;
  147. static int attrib[10];
  148.  
  149. int scroll_log(int actline)
  150. {  /* rotate log lines */
  151.   int i;
  152.   int line;
  153.  
  154.   if(actline < NUMLINES-1) return(actline+1);
  155.   line = line_tab[0];
  156.   for(i=0; i<NUMLINES-1; i++)
  157.   {
  158.     line_tab[i] = line_tab[i+1];
  159.   }
  160.   line_tab[NUMLINES-1] = line;
  161.   return(NUMLINES-1);
  162. }
  163.  
  164. int log(char *str)
  165. {
  166.   int i;
  167.   char *s;
  168.   int len,inline;
  169.  
  170.   if(!str) return(0);
  171.   len = (int)strlen(str);
  172.   if(str[len-1] == '\r')
  173.   {
  174.     str[len-1] = 0;
  175.     inline = 1;
  176.     len--;
  177.   }
  178.   else inline = 0;
  179.   
  180.   log_text[line_tab[actline]][0] = 0;
  181.   if(!len)
  182.     actline = scroll_log(actline);
  183.   s = log_text[line_tab[actline]];
  184.   while(len)
  185.   {
  186.     for(i=0; i <= LINESIZE; i++)
  187.     {
  188.       *s++ = str[i];
  189.       if(!str[i]) break;
  190.       len--;
  191.     }
  192.     *s=0;
  193.     if(!inline) actline = scroll_log(actline);
  194.     if(!inline) s = log_text[line_tab[actline]];
  195.   }
  196.   *s = 0;
  197.   redraw_window(1);
  198.   return(1);
  199. }
  200.  
  201. void open_window( void )
  202. {
  203.   if(whandle <= 0)
  204.   {
  205.     whandle = wind_create(NAME|CLOSER|MOVER, 0, 0, max_x + 1, max_y + 1 );
  206.     if( whandle <= 0 )
  207.       return;
  208.  
  209.     wind_set(whandle, WF_NAME, title);
  210.     vst_font(handle, 1);  /* auswählen       */
  211.     vst_height(handle, ZH, &dum,&dum,&cell_width,&line_height);  /* set small font   */
  212.     vqt_attributes( handle, attrib );
  213.     vst_alignment(handle, 0, 4, &dum, &dum);
  214.     wind_calc(WC_BORDER, NAME|CLOSER|MOVER , 80, 80, cell_width*LINESIZE, line_height*NUMLINES, &x, &y, &w, &h);
  215.     wind_open(whandle, x,y,w,h+15);
  216.   }
  217.   else
  218.     wind_set( whandle, WF_TOP );
  219. }
  220.  
  221. /* -------------------------------------------------------------------- */
  222. /*    min()                                                             */
  223. /*                                                                      */
  224. /*    Minimum zweier Zahlen berechnen.                                  */
  225. /* -------------------------------------------------------------------- */
  226.  
  227. int min( int a, int b)
  228. {
  229.   if( a > b )
  230.     return( b );
  231.   else
  232.     return( a );
  233. }
  234.  
  235. /* -------------------------------------------------------------------- */
  236. /*    max()                                                             */
  237. /*                                                                      */
  238. /*    Maximum zweier Zahlen bestimmen.                                  */
  239. /* -------------------------------------------------------------------- */
  240.  
  241. int max( int a, int b)
  242. {
  243.   if( a < b )
  244.     return( b );
  245.   else
  246.     return( a );
  247. }
  248.  
  249. /* -------------------------------------------------------------------- */
  250. /*    rc_intersect()                                                    */
  251. /*                                                                      */
  252. /*    Schnittfläche zweier Rechtecke berechnen.                         */
  253. /* -------------------------------------------------------------------- */
  254.  
  255. int rc_intersect(GRECT *r1, GRECT *r2)
  256. {
  257.   int xl, yu, xr, yd;  /* left, upper, right, down */
  258.  
  259.   xl      = max( r1->g_x, r2->g_x );
  260.   yu      = max( r1->g_y, r2->g_y );
  261.   xr      = min( r1->g_x + r1->g_w, r2->g_x + r2->g_w );
  262.   yd      = min( r1->g_y + r1->g_h, r2->g_y + r2->g_h );
  263.  
  264.   r2->g_x = xl;
  265.   r2->g_y = yu;
  266.   r2->g_w = xr - xl;
  267.   r2->g_h = yd - yu;
  268.  
  269.   return( r2->g_w > 0 && r2->g_h > 0 );
  270. }
  271.  
  272. /* -------------------------------------------------------------------- */
  273. /*    mouse_on()                                                        */
  274. /*                                                                      */
  275. /*    Mauszeiger anschalten.                                            */
  276. /* -------------------------------------------------------------------- */
  277.  
  278. void mouse_on(void)
  279.  
  280. {
  281.   graf_mouse( M_ON, (void *)0 );
  282. }
  283.  
  284. /* -------------------------------------------------------------------- */
  285. /*    mouse_off()                                                       */
  286. /*                                                                      */
  287. /*    Mauszeiger ausschalten.                                           */
  288. /* -------------------------------------------------------------------- */
  289.  
  290. void mouse_off(void)
  291. {
  292.   graf_mouse( M_OFF, (void *)0 );
  293. }
  294. /* -------------------------------------------------------------------- */
  295. /*    redraw_window()                                                   */
  296. /*                                                                      */
  297. /*    Fensterinhalt neu zeichnen, nachdem er zuvor aus irgendeinem      */
  298. /*    Grunde zerstört wurde, oder weil das Fenster neu geöffnet wurde.  */
  299. /* -------------------------------------------------------------------- */
  300.  
  301. void redraw_window( int all )
  302. {
  303.   GRECT   box,
  304.   work;
  305.   int     clip[4];
  306.   int     line,dum;
  307.   int         height;
  308.  
  309.   if( whandle <= 0 )  /* Wenn kein Fenster auf ist,    */
  310.     return;  /* braucht auch nicht gezeichnet */
  311.   /* zu werden.                    */
  312.  
  313.   if(all)
  314.   {
  315.  
  316.     mouse_off();
  317.  
  318.     vsf_color( handle, 0 );  /* set white fill   */
  319.     vswr_mode( handle, 1 );  /* set replace mode */
  320.     vst_height( handle, 6, &dum,&dum,&dum,&height);  /* set small font   */
  321.  
  322.     wind_get( whandle, WF_WORKXYWH, &work.g_x, &work.g_y, &work.g_w,
  323.     &work.g_h );
  324.     wind_get( whandle, WF_FIRSTXYWH, &box.g_x, &box.g_y, &box.g_w,
  325.     &box.g_h );
  326.     work.g_w = min( work.g_w, max_x - work.g_x + 1 );
  327.     work.g_h = min( work.g_h, max_y - work.g_y + 1 );
  328.  
  329.     while ( box.g_w > 0 && box.g_h > 0 )
  330.     {
  331.       if( rc_intersect( &work, &box ) )
  332.       {
  333.         clip[0] = box.g_x;
  334.         clip[1] = box.g_y;
  335.         clip[2] = box.g_x + box.g_w - 1;
  336.         clip[3] = box.g_y + box.g_h - 1;
  337.  
  338.         vs_clip( handle, 1, clip );
  339.         if( all )
  340.           vr_recfl( handle, clip );
  341.         /* fill rectangle */
  342.         for(line=0;line < NUMLINES; line++)
  343.         {
  344.           v_gtext( handle, work.g_x, work.g_y + 15 + (line*height),log_text[line_tab[line]]);
  345.         }
  346.  
  347.       }
  348.       wind_get( whandle, WF_NEXTXYWH, &box.g_x, &box.g_y, &box.g_w,
  349.       &box.g_h );
  350.     }
  351.     mouse_on();
  352.   }
  353. }
  354.  
  355. /* -------------------------------------------------------------------- */
  356. /*    handle_message()                                                  */
  357. /*                                                                      */
  358. /*    Auswertung der Ereignisse des Multi-Events bezüglich des Message- */
  359. /*    buffers.                                                          */
  360. /* -------------------------------------------------------------------- */
  361.  
  362. int handle_message(int *pipe)
  363. {
  364.   switch ( pipe[0] )
  365.   {
  366.   case WM_REDRAW:
  367.     redraw_window(1);
  368.     break;
  369.  
  370.   case WM_TOPPED:
  371.     wind_set( whandle, WF_TOP );
  372.     break;
  373.  
  374.   case WM_CLOSED:
  375.     if( pipe[3] == whandle )
  376.     {
  377.       wind_close( whandle );
  378.       wind_delete( whandle );
  379.       whandle = 0;
  380.     }
  381.     if( _app )
  382.       return(1);
  383.     break;
  384.  
  385.   case WM_MOVED:
  386.   case WM_SIZED:
  387.     if( pipe[3] == whandle )
  388.       wind_set( whandle, WF_CURRXYWH,  pipe[4], pipe[5],
  389.       pipe[6], pipe[7] );
  390.     break;
  391.  
  392.   case AC_OPEN:
  393.     if( pipe[4] == menu_id )
  394.     {
  395.         sprintf(text,"file %s (%ld wr) %d ov-%ld bf/cl %d",path,ox,or,ix,closeflag);
  396.         log(text);
  397.         open_window();
  398.     }
  399.     break;
  400.  
  401.   case AC_CLOSE:
  402.     if( pipe[3] == menu_id )
  403.       whandle = 0;
  404.     break;
  405.   }
  406.   return(0);
  407. }
  408.  
  409. /* -------------------------------------------------------------------- */
  410. /*    event_loop()                                                      */
  411. /*                                                                      */
  412. /*    Die Multi-Event-Schleife.                                         */
  413. /* -------------------------------------------------------------------- */
  414.  
  415. void event_loop( void )
  416. {
  417.   quit = 0;
  418.   do
  419.   {
  420.     event = evnt_multi( MU_MESAG | MU_TIMER,
  421.     2, 0x1, 1,
  422.     0, 0, 0, 0, 0,
  423.     0, 0, 0, 0, 0,
  424.     pipe,
  425.     100, 0,
  426.     &ex, &ey, &state, &kstate, &key, &clicks );
  427.  
  428.     wind_update(BEG_UPDATE);
  429.  
  430.     if( event & MU_MESAG)
  431.       quit = handle_message( pipe );
  432.     wind_update(END_UPDATE);
  433.  
  434.     if( event & MU_TIMER)
  435.     {
  436.       spool();
  437.       if(printflag)
  438.       {
  439.         open_window();
  440.         log(text);
  441.         sprintf(text,"file %s (%ld wr) %d ov-%ld bf/cl %d",path,ox,or,ix,closeflag);
  442.         sprintf(text,"attempt to print file %s ...",path);
  443.         log(text);
  444.         file_to_print = path;
  445.         spoolfile();
  446.         if(tcp_ok)
  447.         {
  448.          sprintf(text,"File %s printed.",&path);
  449.          log(text);
  450.         }
  451.         /*wind_close( whandle );
  452.         wind_delete( whandle );
  453.         whandle = 0;*/
  454.         printflag = 0;
  455.       }
  456.     }
  457.   }
  458.   while (!quit);
  459. }
  460.  
  461. void multi( void )
  462. {
  463.   do
  464.   {
  465.     event = evnt_multi( MU_MESAG | MU_TIMER,
  466.     2, 0x1, 1,
  467.     0, 0, 0, 0, 0,
  468.     0, 0, 0, 0, 0,
  469.     pipe,
  470.     10, 0,
  471.     &ex, &ey, &state, &kstate, &key, &clicks );
  472.  
  473.     wind_update(BEG_UPDATE);
  474.  
  475.     if( event & MU_MESAG) quit = handle_message( pipe );
  476.     wind_update(END_UPDATE);
  477.     if(quit)
  478.     {
  479.       tcp_close(tcp);
  480.       break;
  481.     }
  482.     if( event & MU_TIMER) break;
  483.   }
  484.   while (1);
  485. }
  486.  
  487. /* -------------------------------------------------------------------- */
  488. /*    main()                                                            */
  489. /*                                                                      */
  490. /*    Kernstück des Programms.                                          */
  491. /* -------------------------------------------------------------------- */
  492.  
  493. int main( void )
  494. {
  495.   int i;
  496.   int work_in[11];
  497.   int work_out[57];
  498.  
  499.   /* ----------------------------------------------------------------- */
  500.   /* Initialization                                                    */
  501.   /* ----------------------------------------------------------------- */
  502.  
  503.   appl_id = appl_init();
  504.   if( appl_id != -1 )
  505.   {
  506.     for (i = 0; i < 10; i++)
  507.       work_in[i]  = 1;
  508.     work_in[10] = 2;
  509.     phys_handle = graf_handle( &gl_wchar, &gl_hchar, &gl_wbox,
  510.     &gl_hbox );
  511.     whandle = 0;
  512.     handle = phys_handle;
  513.     v_opnvwk( work_in, &handle, work_out );
  514.     for(i=0; i< NUMLINES; i++)        /* init log table */
  515.     {
  516.         line_tab[i] = i;
  517.         log_text[i][0] = 0;
  518.     }
  519.     actline = 0;
  520.     if( handle != 0 )
  521.     {
  522.       max_x = work_out[0];
  523.       max_y = work_out[1];
  524.       oldbios = (long)Setexc(45, (void (*)())&grpbios);
  525.       oldgem = (long)Setexc(33, (void (*)())&grpgem);
  526.  
  527.       term = (char *)getenv("FSTEMP");
  528.       if(!term)   strcpy(path,"C:\\tmp");
  529.       else   strcpy(path,term);
  530.       if(path[strlen(path)-1] != '\\') strcat(path,"\\");
  531. if(_app)
  532. {
  533.       strcpy(path,"C:\\environ.dat");
  534.       printflag = 1;
  535. }
  536.       printer = (char *)getenv("PRINTER");
  537.       if(!printer)   printer = "lp";
  538.       user = (char *)getenv("USER");
  539.       if(!user)   user = "ST-HPspd";
  540.       hostname = (char *)getenv("HOSTNAME");
  541.       if(!hostname)   hostname = "SOME-ST";
  542.       printhost = (char *)getenv("PRINTHOST");
  543.       if(!printhost)  printhost = "fortec";
  544.  
  545.       if( !_app )
  546.       {
  547.         menu_id = menu_register( appl_id, "  HPSpoold" );
  548.         /*open_window();*/
  549.       }
  550.       else
  551.       {
  552.         graf_mouse( 0, (void*)0 );
  553.         open_window();
  554.       }
  555.       /* ----------------------------------------------------------------- */
  556.       /* Event Loop                                                        */
  557.       /* ----------------------------------------------------------------- */
  558.  
  559.       sprintf(text,"No file active...");
  560.       log(text);
  561.       event_loop();
  562.  
  563.       /* ----------------------------------------------------------------- */
  564.       /* Deinitialization                                                  */
  565.       /* ----------------------------------------------------------------- */
  566.  
  567.       oldgem = (long)Setexc(33, (void (*)())oldgem);
  568.       oldbios = (long)Setexc(45, (void (*)())oldbios);
  569.       v_clsvwk( handle );
  570.     }
  571.     appl_exit();
  572.   }
  573.   return(0);
  574. }
  575.  
  576. /* -------------------------------------------------------------------- */
  577. /*    End of SPOOLD.C                                                     */
  578. /* -------------------------------------------------------------------- */
  579.  
  580. void spoolfile(void)
  581. {
  582.   tcp_ok = FALSE;
  583.   sprintf(text,"Trying 4.3 bsd print server %s, device %s ...",printhost,printer);
  584.   log(text);
  585.   Supexec(set_pd);
  586.   fin = Fopen(file_to_print, 0);
  587.   Supexec(restore_pd);
  588.  
  589.   if(fin < 0) 
  590.   {
  591.     sprintf(text,"<Error: can't open file '%s'>", file_to_print);
  592.     log(text);
  593.     tcp_ok = FALSE;
  594.   }
  595.   else
  596.   {
  597.     timev = clock();
  598.     number = (((timev >> 24) & 0xff) + ((timev >> 16) & 0xff))*15 +
  599.         ((timev >> 10) );
  600.     Supexec(set_pd);
  601.     filelength = Fseek(0L, fin, SEEK_END);
  602.     Fseek(0L, fin, SEEK_SET);
  603.     Supexec(restore_pd);
  604.     lensent = 0;    
  605.     if((tcp = connect(printhost,LPR_PORT)) > 0)
  606.     {
  607.       tcp_ok = TRUE;
  608.       printfile(fin); 
  609.       tcp_close(tcp);
  610.     }
  611.     else
  612.     {
  613.       sprintf(text,"<Error: no response from %s>",printhost);
  614.       log(text);
  615.       tcp_ok = FALSE;
  616.     }
  617.     Supexec(set_pd);
  618.     Fclose(fin);
  619.     if(!_app) Fdelete(file_to_print);
  620.     Supexec(restore_pd);
  621.   }
  622. }
  623. /* open a connection and return tcp handle, 0 if error */
  624.  
  625. int connect(char * host, int port)
  626. {
  627.   int tcp_id, state;
  628.  
  629.   term = (char *)getenv("TCPWND");
  630.   if(term) tcp_buff = atoi(term);
  631.  
  632.   desti.Port = port;
  633.   if(GetIPAddr(host,desti.IPAddr))
  634.   {
  635.     unsigned int tmp1,tmp2,tmp3,tmp4;
  636.  
  637.     if(sscanf(host,"%d.%d.%d.%d",&tmp1,&tmp2,&tmp3,&tmp4) != 4)
  638.     {
  639.       sprintf(text,"<Error: unknown host.>");
  640.       log(text);
  641.       return 0;
  642.     }
  643.     desti.IPAddr[0] = tmp1;
  644.     desti.IPAddr[1] = tmp2;
  645.     desti.IPAddr[2] = tmp3;
  646.     desti.IPAddr[3] = tmp4;
  647.   }
  648.   tcp_id = (unsigned)tcp_open(721+(int)(Random() % 10),&desti,AKTIV,60,(long)tcp_buff);
  649.  
  650.   if(tcp_id == 0)
  651.   {
  652.     sprintf(text,"<Error: could not open connection.>");
  653.     log(text);
  654.     return 0;
  655.   }
  656.   do
  657.   {
  658.     state = (int)tcp_stat(tcp_id,&tstat);
  659.     if((state > ESTABLISHED) || (state <= CLOSED)) break;
  660.     multi();
  661.   }
  662.   while(state < ESTABLISHED);
  663.  
  664.   if(state != ESTABLISHED)
  665.   {
  666.     sprintf(text,"<Error: connection refused.>");
  667.     log(text);
  668.     return 0;
  669.   }
  670.   return(tcp_id);
  671. }
  672.  
  673. void printfile(int fin)
  674. {
  675.   /* connection is open, start the lprd protocol */
  676.   sprintf(data, "\2%s\n",printer);
  677.   output(data);
  678.   if(get_response() > 1)
  679.   {
  680.     sprintf(text,"%s",data);
  681.     log(text);
  682.   }
  683.   if(response == '\1') 
  684.   {
  685.     sprintf(text,"<Error: printer server didn't accept printer>");
  686.     log(text);
  687.     tcp_ok = FALSE;
  688.     return;
  689.   }
  690.   else if(response != '\0') 
  691.   {
  692.     tcp_ok = FALSE;
  693.     return;
  694.   }
  695.   sprintf(filename, "fA%03ld%s",(number++) % 999,hostname);
  696.   /* get file length */
  697.   sprintf(data, "\3%ld d%s\n", filelength, filename);
  698.   output(data);
  699.   if(get_response() > 1)
  700.   {
  701.     sprintf(text,"%s",data);
  702.     log(text);
  703.   }
  704.   if(response == '\1') 
  705.   {
  706.     sprintf(text,"<Error: connection messed up, try again>");
  707.     log(text);
  708.     tcp_ok = FALSE;
  709.     return;
  710.   }
  711.   else if(response == '\2') 
  712.   {
  713.     sprintf(text,"<Error: server out of storage space>");
  714.     log(text);
  715.     tcp_ok = FALSE;
  716.     return;
  717.   }
  718.   else if(response != '\0') 
  719.   {
  720.     tcp_ok = FALSE;
  721.     return;
  722.   }
  723.  
  724.   do
  725.   {
  726.     Supexec(set_pd);
  727.     lendata = Fread(fin,mmin((long)FILE_BUF_SIZE,filelength),file_buffer);
  728.     Supexec(restore_pd);
  729. #ifdef DEBUG
  730.     printf("read %ld bytes\n",lendata);
  731. #endif
  732.     if(lendata <= 0)
  733.     {
  734.       file_buffer[0] = 0;
  735.       output1(1,file_buffer);
  736.     }
  737.     if(lendata < 0)
  738.     {
  739.       return;
  740.     }
  741.     lensent += lendata;
  742.     sprintf(text,"%ld %%\r",(lensent * 100) / filelength);
  743.     log(text);
  744.     output1((int)lendata,file_buffer);
  745.     multi();
  746.   }
  747.   while(lendata > 0);      
  748.  
  749.   if(get_response() > 1)
  750.   {
  751.     sprintf(text,"%s",data);
  752.     log(text);
  753.   }
  754.   if(response != '\0') 
  755.   {
  756.     sprintf(text,"<Error: data file not properly transferred, aborting>");
  757.     log(text);
  758.     tcp_ok = FALSE;
  759.     return;
  760.   }
  761. #ifdef DEBUG
  762.   printf("file closed\n");
  763. #endif
  764.   /* build the control file */
  765.   sprintf(file_buffer, "H%s\n",hostname);
  766.   sprintf(file_buffer+strlen(file_buffer), "P%s\n", user);
  767.   sprintf(file_buffer+strlen(file_buffer), "J%s\n", file_to_print);
  768.   sprintf(file_buffer+strlen(file_buffer), "C%s\n", hostname);
  769.   sprintf(file_buffer+strlen(file_buffer), "L%s\n", user);
  770.   sprintf(file_buffer+strlen(file_buffer), "fd%s\n", filename);
  771.   sprintf(file_buffer+strlen(file_buffer), "Ud%s\n", filename);
  772.   sprintf(file_buffer+strlen(file_buffer), "N%s\n", file_to_print);
  773.   sprintf(data, "\2%ld c%s\n", strlen(file_buffer), filename);
  774.   output(data);
  775.   if(get_response() > 1)
  776.   {
  777.     sprintf(text,"%s",data);
  778.     log(text);
  779.   }
  780.   if(response == '\1') 
  781.   {
  782.     sprintf(text,"<Error: connection messed up, try again>");
  783.     log(text);
  784.     tcp_ok = FALSE;
  785.     return;
  786.   }
  787.   else if(response == '\2') 
  788.   {
  789.     sprintf(text,"<Error: server out of storage space>");
  790.     log(text);
  791.     tcp_ok = FALSE;
  792.     return;
  793.   }
  794.   else if(response != '\0') 
  795.   {
  796.     tcp_ok = FALSE;
  797.     return;
  798.   }
  799.   output1((int)strlen(file_buffer)+1,file_buffer);
  800.   if(get_response() > 1)
  801.   {
  802.     sprintf(text,"%s",data);
  803.     log(text);
  804.   }
  805.   if(response != '\0') 
  806.   {
  807.     sprintf(text,"<Error: control file not properly transferred, aborting>");
  808.     log(text);
  809.     tcp_ok = FALSE;
  810.     return;
  811.   }
  812. }
  813.  
  814. void output(char *o_str)
  815. {
  816.   int o_len;
  817.  
  818.   o_len = (int)strlen(o_str);
  819.   output1(o_len, o_str);
  820. }
  821.  
  822. void output1(int o_len, char *o_str)
  823. {
  824.   int i,j;
  825.  
  826.   for(i=0; i < o_len;)
  827.   {
  828.     j = (int)tcp_write(tcp,o_str+i,o_len-i,PUSH,NO_URGENT);
  829.     if(j>=0) i += j;
  830.     else
  831.     {
  832.       sprintf(text,"connection broken");
  833.       log(text);
  834.       tcp_ok = FALSE;
  835.       break;
  836.     }
  837.     multi();
  838. #ifdef DEBUG
  839.     printf("send %d bytes\n",j);
  840. #endif
  841.   }
  842. }
  843.  
  844. int get_response(void)
  845. {
  846.   int length;
  847.  
  848.   do
  849.   {
  850.     multi();
  851.     length = (int)tcp_read(tcp,data,INBUFSIZE);
  852.   } 
  853.   while(!length);
  854.   if(length < 0) return length;
  855.   response = data[0];
  856.   return length;
  857. }
  858.  
  859. long gemclose(void)
  860. {
  861.   flag = 1;
  862.   if(fh) Fclose(fh);
  863.   fh = 0;
  864.   flag = 0;
  865.   printflag = 1;
  866.   return 0;
  867. }
  868.  
  869. long gembuffer(long count,char *tbuf)
  870. {
  871.   flag = 1;
  872.  
  873.   if(fh <= 0)
  874.   {
  875.    spfilename[7]++;
  876.    spfilename[7] &= 0x07;
  877.    spfilename[7] |= '0';
  878.    strcpy(strrchr(path,'\\')+1,spfilename);
  879.    Supexec(set_pd);
  880.    fh = Fcreate(path,0);
  881.    Supexec(restore_pd);
  882.    ox = 0;
  883.   }
  884.   Supexec(set_pd);
  885.   if(Fwrite(fh,count,tbuf) < 0) fh = 0;
  886.   Supexec(restore_pd);
  887.   ox += count;
  888.   flag = 0;
  889.   return count;
  890. }
  891.  
  892. int biosbuffer(int zeichen)
  893. {
  894.  if(ix < BUFS) bf[ix++] = zeichen & 0xff;
  895.  else
  896.  {
  897.   ix = 0;
  898.   or++;
  899.  }
  900.  
  901.  if(escflag)
  902.  {
  903.   if(zeichen == 'E')
  904.   {
  905.    closeflag = ix;
  906.   }
  907.   escflag = 0;
  908.  }
  909.  if(zeichen == 0x1b) escflag = 1;
  910.  spool();
  911.  return -1;
  912. }
  913.  
  914. void spool(void)
  915. {
  916.  flag = 1;
  917.  if(ix >= BUFS/2 || closeflag)
  918.  {
  919.   if(fh <= 0)
  920.   {
  921.    spfilename[7]++;
  922.    spfilename[7] &= 0x07;
  923.    spfilename[7] |= '0';
  924.    strcpy(strrchr(path,'\\')+1,spfilename);
  925.    Supexec(set_pd);
  926.    fh = Fcreate(path,0);
  927.    Supexec(restore_pd);
  928.    ox = 0;
  929.    if(fh < 0)
  930.    {
  931.     flag = 0;
  932.     return;
  933.    }
  934.   }
  935.   
  936.   if(closeflag && ((ix > 2) || ox))
  937.   {
  938.    Supexec(set_pd);
  939.    Fwrite(fh,closeflag,bf);
  940.    Fclose(fh);
  941.    Supexec(restore_pd);
  942.    ox += closeflag;
  943.    fh = 0;
  944.    or = 0;
  945.    printflag = 1;
  946.    memcpy(bf,&bf[closeflag],ix-closeflag);
  947.    ix = ix-closeflag;
  948.    closeflag = 0;
  949.   }
  950.   else
  951.   {
  952.    Supexec(set_pd);
  953.    if(Fwrite(fh,ix,bf) < 0) fh = 0;
  954.    Supexec(restore_pd);
  955.    ox += ix;
  956.    ix = 0;
  957.    closeflag = 0;
  958.   }
  959.  }
  960.  flag = 0;
  961.  
  962.  
  963. long set_pd(void)
  964. {
  965.   oldpd = SYSBASE->_run;
  966.   SYSBASE->_run = &_BasPag;
  967.   return 0;
  968. }
  969.  
  970. long restore_pd(void)
  971. {
  972.   SYSBASE->_run = oldpd;
  973.   return 0;
  974. }
  975.